package cn.cj.erp.serviceimpl.system;

import cn.cj.erp.common.utils.Convert;
import cn.cj.erp.bo.system.SysRoleBo;
import cn.cj.erp.service.system.SysRoleDeptService;
import cn.cj.erp.service.system.SysRoleMenuService;
import cn.cj.erp.service.system.SysRoleService;
import cn.cj.erp.service.system.SysUserRoleService;
import cn.cj.erp.serviceimpl.base.ServiceImpl;
import cn.cj.erp.utils.PermissionUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.cj.erp.common.enums.DataScopeTypeEnum;
import cn.cj.erp.common.exception.ServiceException;
import cn.cj.erp.entity.system.SysRole;
import cn.cj.erp.dao.system.SysRoleDao;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 角色
 *
 * @author chenjian
 */
@Slf4j
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRole, SysRoleBo>
        implements SysRoleService {
    @Resource
    private SysRoleDao sysRoleDao;
    @Resource
    private SysRoleMenuService sysRoleMenuService;
    @Resource
    private SysRoleDeptService sysRoleDeptService;
    @Resource
    private SysUserRoleService sysUserRoleService;

    @Override
    public SysRoleDao getBaseMapper() {
        return sysRoleDao;
    }

    @Override
    public SysRole convert2Entity(SysRoleBo bo) {
        return Convert.convert(bo, SysRole.class);
    }

    @Override
    public SysRoleBo convert2Bo(SysRole sysRole) {
        return Convert.convert(sysRole, SysRoleBo.class);
    }

    /**
     * 根据ID获取菜单权限列表
     *
     * @param id 主键
     * @return 菜单权限列表
     */
    @Override
    public Set<String> listMenuPermById(Long id) {
        List<String> perms = getBaseMapper().listMenuPermById(id);
        return PermissionUtil.handlePermission(perms);
    }

    /**
     * 批量处理数据，包括报错、新增
     * @param list 角色列表
     * @return boolean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveBatch(List<SysRoleBo> list) {
        if(CollectionUtil.isEmpty(list)){
            log.info("SysRoleServiceImpl batchSaveRole 没有需要新增或更新的数据，直接返回成功");
            return true;
        }
        for (SysRoleBo sysRole : list) {
            if (sysRole.getRoleId() == null) {
                sysRole.setDataScope(DataScopeTypeEnum.CUSTOM);
                this.save(sysRole);
            } else {
                this.updateById(sysRole);
            }
        }
        return true;
    }

    /**
     * 批量处理数据，包括报错、新增
     * @param list 角色列表
     * @return boolean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchDeleteRole(List<SysRoleBo> list) {
        if (CollectionUtil.isEmpty(list)) {
            log.info("SysRoleServiceImpl batchDeleteRole 没有需要删除的数据，直接返回成功");
            return true;
        }
        List<Long> ids = list.stream().map(SysRoleBo::getRoleId).collect(Collectors.toList());
        //删除角色与菜单关联
        sysRoleMenuService.removeByRoleIds(ids);
        //删除角色与部门关联
        sysRoleDeptService.removeByRoleIds(ids);
        //删除角色与用户关联
        sysUserRoleService.removeByRoleIds(ids);
        //删除角色
        boolean result = this.removeByIds(ids);
        if (!result) {
            rollback();
            log.error("角色删除失败");
            return false;
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean authDataScope(SysRoleBo bo) {
        boolean result = this.updateById(bo);
        if (!result) {
            throw new ServiceException("更新角色失败");
        }
        //删除角色与部门关联
        sysRoleDeptService.removeByRoleId(bo.getRoleId());
        // 若是自定义数据权限，则新增角色部门数据
        if (DataScopeTypeEnum.CUSTOM.equals(bo.getDataScope())
                && CollectionUtil.isNotEmpty(bo.getDeptIds())) {
            result = sysRoleDeptService.saveAllDeptToRole(bo.getRoleId(), bo.getDeptIds());
            if (!result) {
                throw new ServiceException("新增角色部门失败");
            }
        }
        return true;
    }

    @Override
    public List<SysRoleBo> list() {
        return convert2BoList(getBaseMapper().selectList(null));
    }


}
